<#assign packageModel=projPackage.entity valuePrefix="#{"
        serviceImplPackage=projPackage.projPackage+"."+projPackage.service
        serviceFullPackage=projPackage.projPackage+"."+projPackage.service+ "." + tableInfo.modelClassName + "Service"
        daoPackageAndClass=projPackage.projPackage+"."+projPackage.dao+"."+tableInfo.modelClassName+"Mapper"
        modelPackageAndClass=projPackage.projPackage+"."+projPackage.entity+"."+tableInfo.modelClassName
        utilsFullPackage=projPackage.projPackage + "." + projPackage.utils
        >
package ${serviceImplPackage};

import java.util.Optional;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import ${daoPackageAndClass};
import ${modelPackageAndClass};
import ${utilsFullPackage}.BusinessException;
import ${utilsFullPackage}.Example;

/**
 * 版本号：20240401
 * @Description : 服务层实现类，自定义代码写在最后，不要插在中间
 * @Author : chanchaw
 * @Date : ${.now?date} ${.now?time}
 */
@Service
public class ${tableInfo.modelClassName}ServiceImpl implements ${tableInfo.modelClassName}Service {
    @Autowired
    private ${tableInfo.modelClassName}Mapper dao;

    @Lazy
    @Autowired
    private ${tableInfo.modelClassName}Service meService;

    @Override
    @Transactional
    public ${tableInfo.modelClassName} insert(${tableInfo.modelClassName} record) {
        meService.check4Insert(record);
        record = meService.fullFill(record);
        meService.doBeforeInsert(record);
        dao.insert(record);
        meService.doAfterInsert(record);
        return record;
    }

    @Override
    @Transactional
    public ${tableInfo.modelClassName} insertSelective(${tableInfo.modelClassName} record) {
        meService.check4Insert(record);
        record = meService.fullFill(record);
        doBeforeInsert(record);
        dao.insertSelective(record);
        meService.doAfterInsert(record);
        return record;
    }

    /* 由于本方法无法返回所有对象的自增主键，后者调整为一个一个保存的方法
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiInsert(List<${tableInfo.modelClassName}> list) {
        return dao.multiInsert(list);
    }
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<${tableInfo.modelClassName}> multiInsert(List<${tableInfo.modelClassName}> list) {
        list.forEach(item -> meService.insertSelective(item));
        return list;
    }

    @Override
    public int updateByPrimaryKey(${tableInfo.modelClassName} record) {
        checkSid4Update(record);
        return dao.updateByPrimaryKey(record);
    }

    @Override
    public int updateByPrimaryKeySelective(${tableInfo.modelClassName} record) {
        checkSid4Update(record);
        return dao.updateByPrimaryKeySelective(record);
    }

    <#list tableInfo.fieldInfoList as field>
    <#if field.primaryKey=true>
    @Override
    public int deleteByPrimaryKey(${field.javaType} ${field.fieldName}) {
        return dao.deleteByPrimaryKey(${field.fieldName});
    }

    @Override
    public ${tableInfo.modelClassName} selectByPrimaryKey(${field.javaType} ${field.fieldName}) {
        return dao.selectByPrimaryKey(${field.fieldName});
    }
    </#if>
    </#list>

    @Override
    public List<${tableInfo.modelClassName}> selectAll(){
        return dao.selectAll();
    }

    @Override
    public ${tableInfo.modelClassName} save(${tableInfo.modelClassName} record){
        if(record == null) throw new BusinessException("空对象不可保存！");
        Integer iid = Optional.ofNullable(record.getIid()).orElse(0);
        if(iid.equals(0)) record = insertSelective(record);
        else updateByPrimaryKeySelective(record);
        return record;
    }

    // 没有使用 xml 中的 multiSave 方法是因为无法批量回写自增主键
    @Transactional
    @Override
    public List<${tableInfo.modelClassName}> multiSave(List<${tableInfo.modelClassName}> list){
        if(list == null || list.size()==0) return list;
        list.forEach(item -> item = meService.save(item));
        return list;
    }

    /**=========================下面开始是固定模式代码=======================================*/
    public ${tableInfo.modelClassName} selectBySid(String sid){
        return dao.selectBySid(sid);
    }

    // 返回true表示存在，false表示不存在
    // 基础资料都以字段 sid 为关键标识，自增主键 iid 备用
    public Boolean exists(String sid){
        ${tableInfo.modelClassName} record = selectBySid(sid);
        return record == null ? false : true;
    }

    // 新增前调用本方法将对象填充完整，然后调用 doBeforeInsert 再进行插入
    @Override
    public ${tableInfo.modelClassName} fullFill(${tableInfo.modelClassName} record) {
        // TODO: 默认前端传递来的参数不需要填充完整，如果需要则使用自定义逻辑覆盖下面的代码
        return ${tableInfo.modelClassName}Service.super.fullFill(record);
    }

    // 新增前调用的方法，抛出异常则不会新增数据
    @Override
    public void doBeforeInsert(${tableInfo.modelClassName} record) {
        ${tableInfo.modelClassName}Service.super.doBeforeInsert(record);
    }

    // 新增后调用的方法
    @Override
    public void doAfterInsert(${tableInfo.modelClassName} record) {
        ${tableInfo.modelClassName}Service.super.doAfterInsert(record);
    }

    // 是基础资料数据则修改之前要调用本方法
    // 检测修改后的目标 sid 是否已经存在
    // 这里要防止检测到自己 - 根据主键 iid 判断
    private void checkSid4Update(${tableInfo.modelClassName} record){
        if(record == null) throw new BusinessException("传入了空对象，无法修改！");
        Integer iid = Optional.ofNullable(record.getIid()).orElse(0);
        if(iid.equals(0)) throw new BusinessException("没有主键无法修改！");
        ${tableInfo.modelClassName} selectedRecord = selectByPrimaryKey(iid);
        if(selectedRecord == null) throw new BusinessException("主键" +iid+"的数据没有找到！");
        String sid = Optional.ofNullable(record.getSid()).orElse("");
        Example<${tableInfo.modelClassName}> example = new Example<>();
        example.andIn("sid",sid);
        List<${tableInfo.modelClassName}> records = dao.selectByExample(example);
        if(records.size() == 0) return;
        records.forEach(item -> {
            if(!item.getIid().equals(iid)) throw new BusinessException("编号" +sid+"已经存在，请更换后再次保存！");
        });
    }

    @Override
    public List<${tableInfo.modelClassName}> selectByExample(Example<${tableInfo.modelClassName}> example){
        return dao.selectByExample(example);
    }
    //=================以上是自动生成的代码，自定义代码请写在下面==================
}